from nc_mlpa.mlpa.models import MlpaMpa, MpaArray
from django.contrib.auth.models import Group, User 
    
class nc_constants:
    GROUPS = {'com': 'Commercial', 'cpfv': 'Commercial Passenger Fishing Vessel', 'div': 'Recreational Dive', 'kyk': 'Recreational Kayak', 'pvt': 'Recreational Private Vessel', 'swd': 'Edible Seaweed'}
    PORTS = {'all': 'Entire Study Region', 'ab': 'Albion', 'cc': 'Crescent City', 'ek': 'Eureka', 'el': 'Elk', 'fb': 'Fort Bragg', 'sc': 'Shelter Cove', 'td': 'Trinidad'}
    TARGETS = {'abal': ['red abalone'], 'achv': ['coastal pelagic finfish'], 'chal': ['California halibut'], 'dcrab': ['Dungeness crab'], 'dcrabt': ['Dungeness crab'], 'eswd': ['bull kelp', 'sea palm', 'canopy-forming algae'], 'herg': ['coastal pelagic finfish'], 'phal': ['Pacific halibut'], 'rckf': ['rockfishes'], 'rckpo': ['rockfishes'], 'rklc': ['rockfishes'], 'sal': ['salmon'], 'salt': ['salmon'], 'sard': ['coastal pelagic finfish'], 'shrmpt': ['coonstripe shrimp and spot prawn'], 'smtb': ['smelts'], 'sphkl': ['redtail surfperch'], 'urchd': ['urchin']} 
    FISHING_TYPES = {'com': 'commercial', 'cpfv': 'recreational', 'div': 'recreational', 'kyk': 'recreational', 'pvt': 'recreational', 'swd': 'commercial'}
    COMMERCIAL_SPECIES_DISPLAY = {'Anchovies': 'Anchovy/Sardine (Lampara Net)', 'Dungeness Crab': 'Dungeness Crab (Trap)', 'Pacific Herring': 'Herring (Seine)', 'Rockfish': 'Rockfish (Fixed Gear)', 'Salmon': 'Salmon (Troll)', 'Edible Seaweed': 'Seaweed (Hand Harvest)', 'Shrimp': 'Shrimp (Trap)', 'Smelt': 'Smelt (Brail, Dip Net)', 'Surf Perch': 'Surfperch (Hook and Line)', 'Urchin': 'Urchin (Dive)'}
    COMMERCIAL_METHODS = {'achv': ['round-haul net'], 'dcrabt': ['trap'], 'eswd': ['intertidal hand harvest'], 'herg': ['gillnet'], 'rklc': ['trap', 'hook and line'], 'salt': ['troll'], 'sard': ['round-haul net'], 'shrmpt': ['trap'], 'smtb': ['dip net'], 'sphkl': ['hook and line'], 'urchd': ['diving']}
    SPECIES_DISPLAY = {'abal': 'Abalone', 'achv': 'Anchovies', 'chal': 'California Halibut', 'dcrab': 'Dungeness Crab', 'dcrabt': 'Dungeness Crab', 'eswd': 'All Edible Seaweed Species', 'herg': 'Pacific Herring', 'phal': 'Pacific Halibut', 'rckf': 'Rockfish', 'rckpo': 'Rockfish', 'rklc': 'Rockfish', 'sal': 'Salmon', 'salt': 'Salmon', 'sard': 'Sardines', 'shrmpt': 'Shrimp', 'smtb': 'Smelt', 'sphkl': 'Surf Perch', 'urchd': 'Urchin'} 
    REC_CPFV_METHODS = {'chal': ['hook and line'], 'dcrab': ['trap'], 'phal': ['hook and line'], 'rckpo': ['hook and line'], 'sal': ['hook and line']}
    REC_DIV_METHODS = {'abal': ['free dive'], 'dcrab': ['dive'], 'rckf': ['spearfish']}
    REC_KYK_METHODS = {'sal': ['hook and line'], 'rckf': ['hook and line']}
    REC_PVT_METHODS = {'chal': ['hook and line'], 'dcrab': ['trap'], 'phal': ['hook and line'], 'rckf': ['hook and line'], 'sal': ['hook and line']}
        

def num_maps(group, port=None):
    from econ_analysis.models import FishingImpactAnalysisMap
    if port is None:
        ports = GetPortsByGroup(group)
    else:
        ports = [port]
    num_maps = 0
    for port in ports:
        maps = FishingImpactAnalysisMap.objects.filter(group_name=ensure_proper_name(group), port_name=port)
        num_maps += len(maps)
    return num_maps
        
def isCOM(group):
    if group in ['Commercial', 'com']:
        return True
    return False

def isCPFV(group):
    if group in ['Commercial Passenger Fishing Vessel', 'cpfv']:
        return True
    return False
    
def isSWD(group):
    if group in ['Edible Seaweed', 'swd']:
        return True
    return False
    
def isDIV(group):
    if group in ['div', 'Recreational Dive']:
        return True
    return False

def isKYK(group):
    if group in ['kyk', 'Recreational Kayak']:
        return True
    return False

def isPVT(group):
    if group in ['pvt', 'Recreational Private Vessel']:
        return True
    return False
        
def ensure_proper_name(group):    
    if isCOM(group):
        return 'Commercial'
    if isCPFV(group):
        return 'Commercial Passenger Fishing Vessel'
    if isSWD(group):
        return 'Edible Seaweed'
    if isDIV(group):
        return 'Recreational Dive'
    if isKYK(group):
        return 'Recreational Kayak'
    if isPVT(group):
        return 'Recreational Private Vessel'
      
def ensure_abbreviated_name(group):   
    if isCOM(group):
        return 'com'
    if isCPFV(group):
        return 'cpfv'
    if isSWD(group):
        return 'swd'
    if isDIV(group):
        return 'div'
    if isKYK(group):
        return 'kyk'
    if isPVT(group):
        return 'pvt'
      
def GetSpeciesByGroup(group):
    species = []
    if isCOM(group):
        specs = nc_constants.COMMERCIAL_METHODS.keys()
        specs.remove('eswd')
        specs.remove('sard')
    elif isCPFV(group):
        specs = nc_constants.REC_CPFV_METHODS.keys()
    elif isSWD(group):
        specs = ['eswd']
    elif isDIV(group):
        specs = nc_constants.REC_DIV_METHODS.keys()
    elif isKYK(group):
        specs = nc_constants.REC_KYK_METHODS.keys()
    elif isPVT(group):
        specs = nc_constants.REC_PVT_METHODS.keys()
    else:
        raise Exception('invalid group sent to GetSpeciesInGroup')
    for spec in specs:
        species.append(nc_constants.SPECIES_DISPLAY[spec])
    return species

def GetPortsByGroup(group):
    if isCOM(group):
        return ['Crescent City', 'Trinidad', 'Eureka', 'Shelter Cove', 'Fort Bragg', 'Albion']
    if isCPFV(group):
        return ['Crescent City', 'Trinidad', 'Eureka', 'Shelter Cove', 'Fort Bragg']
    if isDIV(group):
        return ['Crescent City', 'Trinidad', 'Eureka', 'Shelter Cove', 'Fort Bragg']
    if isKYK(group):
        return ['Trinidad', 'Fort Bragg']
    if isPVT(group):
        return ['Crescent City', 'Trinidad', 'Eureka', 'Shelter Cove', 'Fort Bragg']
    if isSWD(group):
        return ['Crescent City', 'Elk', 'Fort Bragg']
    raise Exception('invalid group sent to GetPortsInGroup')
       
   
'''
Returns a dictionary associating a list of mpas with a given user
{'user': [list of mpas], ...}
Called by ProcessingTimes.estimate_processing_times and MpaAnalysis.process_user_mpas
''' 
def get_user_mpas(ids):
    user_mpas = {}
    for user_id in ids:
        user = User.objects.get(pk=user_id)
        user_mpas[user] = MlpaMpa.objects.filter(user=user)
    return user_mpas        
  
'''
Returns a dictionary associating a list of mpas with a given group
{'group': [list of mpas], ...}
Note:   Mpas can be associated with a group directly (via the sharing_groups attribute)
        or indirectly by being part of an array that is associated with a group
Called by ProcessingTimes.estimate_processing_times and MpaAnalysis.process_group_mpas
'''   
def get_group_mpas(ids):
    group_mpas = {}
    #traverse through the group ids adding a single list of mpas to group_mpas for each group
    for group_id in ids:
        group = Group.objects.get(pk=group_id)
        mpas = []
        #get the mpas associated with this group
        mpas.extend(MlpaMpa.objects.filter(sharing_groups=group))
        #get the arrays associated with this group
        single_group_arrays = MpaArray.objects.filter(sharing_groups=group)
        for array in single_group_arrays:
            mpas.extend(array.mpa_set)
        #remove any duplicates from the list (there may be overlap between mpas associated with the group and the mpas in each array)
        #and add dictionary entry to group_mpas
        group_mpas[group] = list(set(mpas))
    return group_mpas

'''
Returns a pseudo-random integer between low and high. Defaults to
between 1 and 1 trillion.
'''
def getRandInt(low=1, high=1000000000):
    import random
    return random.randint(low, high) 

'''
A better rounding operation.  Chops off remainder as Python can leave 
repeating decimal places.
'''
def trueRound(num, places=4):
    num = round(num,places)
    format_str = '%.'+str(places)+'f'
    result = format_str % num
    return result

def percentage(one, two):
    return (one/two)*100    